/*
 * HexGame_test.cpp
 *
 *  Created on: Apr 5, 2014
 *      Author: zby
 */

#include "Test_HexGame.h"

CppUnit::Test* Test_HexGame::suite(){
    CppUnit::TestSuite* suiteOfTests = new CppUnit::TestSuite("Test_HexGame");
    suiteOfTests->addTest(new CppUnit::TestCaller<Test_HexGame>("test_def_constructor",&Test_HexGame::test_def_constructor));
    suiteOfTests->addTest(new CppUnit::TestCaller<Test_HexGame>("test_usermenu",&Test_HexGame::test_usermenu));
    suiteOfTests->addTest(new CppUnit::TestCaller<Test_HexGame>("test_usermenu",&Test_HexGame::test_whoWon));
    suiteOfTests->addTest(new CppUnit::TestCaller<Test_HexGame>("test_usermenu",&Test_HexGame::test_userMove));
    suiteOfTests->addTest(new CppUnit::TestCaller<Test_HexGame>("test_usermenu",&Test_HexGame::test_compMove));

    return suiteOfTests;
}

void Test_HexGame::test_def_constructor()
{
    CPPUNIT_ASSERT(hg1->pBoardGame==NULL && 500==hg1->MonteCarloLimit);
}


void Test_HexGame::test_usermenu(void)
{
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> choose: length 15 and 'x'"<<endl<<endl<<endl;
    hg1->usermenu();
    CPPUNIT_ASSERT(true==hg1->isUserPlayerA && 15==hg1->pBoardGame->GetBoardSize());

    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> choose: length 7 and 'o'"<<endl<<endl<<endl;
    hg1->usermenu();
    CPPUNIT_ASSERT(false==hg1->isUserPlayerA && 7==hg1->pBoardGame->GetBoardSize());
}

void Test_HexGame::test_whoWon(void)
{
    //checking if method "whoWon" works ok for x player = PLAYER_A
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> choose: length 7 and 'x'"<<endl<<endl<<endl;
    hg1->usermenu();
    CPPUNIT_ASSERT(true==hg1->isUserPlayerA && 7==hg1->pBoardGame->GetBoardSize());
    //put moves:
    // x:        o:
    //(6,0)        (0,2)
    //(5,1)        (1,2)
    //(4,2)        (2,1)
    //(3,3)        (1,3)
    //(4,3)        (2,3)
    //(5,3)        (3,2)
    //(4,4)        (5,2)
    //(3,5)        (6,1)
    //(3,6)
    hg1->pBoardGame->put_move(6,0,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(0,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg1->whoWon());
    hg1->pBoardGame->put_move(5,1,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(1,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg1->whoWon());
    hg1->pBoardGame->put_move(4,2,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(2,1,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg1->whoWon());
    hg1->pBoardGame->put_move(3,3,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(1,3,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg1->whoWon());
    hg1->pBoardGame->put_move(4,3,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(2,3,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg1->whoWon());
    hg1->pBoardGame->put_move(5,3,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(3,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg1->whoWon());
    hg1->pBoardGame->put_move(4,4,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(5,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg1->whoWon());
    hg1->pBoardGame->put_move(3,5,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(6,1,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg1->whoWon());
    hg1->pBoardGame->put_move(3,6,(_eplayer)PLAYER_A);
    //cout<<*(hg1->pBoardGame)<<endl;
    CPPUNIT_ASSERT(PLAYER_A==hg1->whoWon());

    //checking if method "whoWon" works ok for o player = PLAYER_B
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> choose: length 7 and 'o'"<<endl<<endl<<endl;
    hg2->usermenu();
    CPPUNIT_ASSERT(false==hg2->isUserPlayerA && 7==hg2->pBoardGame->GetBoardSize());
    //put moves:
    // x:        o:
    //(6,0)        (0,2)
    //(5,1)        (1,2)
    //(0,0)        (2,1)
    //(3,3)        (1,3)
    //(4,3)        (2,3)
    //(5,3)        (3,2)
    //(4,4)        (4,2)
    //(3,5)        (5,2)
    //(3,6)        (6,1)
    hg2->pBoardGame->put_move(6,0,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(0,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg2->whoWon());
    hg2->pBoardGame->put_move(5,1,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(1,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg2->whoWon());
    hg2->pBoardGame->put_move(0,0,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(2,1,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg2->whoWon());
    hg2->pBoardGame->put_move(3,3,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(1,3,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg2->whoWon());
    hg2->pBoardGame->put_move(4,3,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(2,3,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg2->whoWon());
    hg2->pBoardGame->put_move(5,3,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(3,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg2->whoWon());
    hg2->pBoardGame->put_move(4,4,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(4,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg2->whoWon());
    hg2->pBoardGame->put_move(3,5,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(5,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg2->whoWon());
    hg2->pBoardGame->put_move(3,6,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(6,1,(_eplayer)PLAYER_B);
    //cout<<*(hg2->pBoardGame)<<endl;
    CPPUNIT_ASSERT(PLAYER_B==hg2->whoWon());

    //checking if method "whoWon" works ok for x player = PLAYER_A in case x come form North to South
    //in this case x not win
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> choose: length 7 and 'x'"<<endl<<endl<<endl;
    hg3->usermenu();
    CPPUNIT_ASSERT(true==hg3->isUserPlayerA && 7==hg3->pBoardGame->GetBoardSize());
    //put moves:
    // x:         o:
    //(0,2)        (6,0)
    //(1,2)        (5,1)
    //(1,3)        (3,3)
    //(2,1)        (4,3)
    //(2,3)        (5,3)
    //(3,2)        (3,2)
    //(4,2)        (4,4)
    //(5,2)        (3,5)
    //(6,1)        (3,6)
    hg3->pBoardGame->put_move(0,2,(_eplayer)PLAYER_A); hg3->pBoardGame->put_move(6,0,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg3->whoWon());
    hg3->pBoardGame->put_move(1,2,(_eplayer)PLAYER_A); hg3->pBoardGame->put_move(5,1,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg3->whoWon());
    hg3->pBoardGame->put_move(1,3,(_eplayer)PLAYER_A); hg3->pBoardGame->put_move(3,3,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg3->whoWon());
    hg3->pBoardGame->put_move(2,1,(_eplayer)PLAYER_A); hg3->pBoardGame->put_move(4,3,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg3->whoWon());
    hg3->pBoardGame->put_move(2,3,(_eplayer)PLAYER_A); hg3->pBoardGame->put_move(5,3,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg3->whoWon());
    hg3->pBoardGame->put_move(3,2,(_eplayer)PLAYER_A); hg3->pBoardGame->put_move(3,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg3->whoWon());
    hg3->pBoardGame->put_move(4,2,(_eplayer)PLAYER_A); hg3->pBoardGame->put_move(4,4,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg3->whoWon());
    hg3->pBoardGame->put_move(5,2,(_eplayer)PLAYER_A); hg3->pBoardGame->put_move(3,5,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg3->whoWon());
    hg3->pBoardGame->put_move(6,1,(_eplayer)PLAYER_A);  hg3->pBoardGame->put_move(3,5,(_eplayer)PLAYER_B);
    //cout<<*(hg3->pBoardGame)<<endl;
    CPPUNIT_ASSERT(NONE==hg3->whoWon());

    //checking if method "whoWon" works ok for 'o' player = PLAYER_B in case 'o' come form West to East
    //in this case 'o' not win
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> choose: length 7 and 'o'"<<endl<<endl<<endl;
    hg4->usermenu();
    CPPUNIT_ASSERT(false==hg4->isUserPlayerA && 7==hg4->pBoardGame->GetBoardSize());
    //put moves:
    // x:         o:
    //(0,2)        (6,0)
    //(1,2)        (5,1)
    //(1,3)        (4,2)
    //(2,1)        (3,3)
    //(2,3)        (4,3)
    //(3,2)        (5,3)
    //(0,0)        (3,2)
    //(5,2)        (4,4)
    //(6,1)        (3,5)
    //(1,0)        (3,6)
    hg4->pBoardGame->put_move(0,2,(_eplayer)PLAYER_A); hg4->pBoardGame->put_move(6,0,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg4->whoWon());
    hg4->pBoardGame->put_move(1,2,(_eplayer)PLAYER_A); hg4->pBoardGame->put_move(5,1,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg4->whoWon());
    hg4->pBoardGame->put_move(1,3,(_eplayer)PLAYER_A); hg4->pBoardGame->put_move(4,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg4->whoWon());
    hg4->pBoardGame->put_move(2,1,(_eplayer)PLAYER_A); hg4->pBoardGame->put_move(3,3,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg4->whoWon());
    hg4->pBoardGame->put_move(2,3,(_eplayer)PLAYER_A); hg4->pBoardGame->put_move(4,3,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg4->whoWon());
    hg4->pBoardGame->put_move(3,2,(_eplayer)PLAYER_A); hg4->pBoardGame->put_move(5,3,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg4->whoWon());
    hg4->pBoardGame->put_move(0,0,(_eplayer)PLAYER_A); hg4->pBoardGame->put_move(3,2,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg4->whoWon());
    hg4->pBoardGame->put_move(5,2,(_eplayer)PLAYER_A); hg4->pBoardGame->put_move(4,4,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg4->whoWon());
    hg4->pBoardGame->put_move(6,1,(_eplayer)PLAYER_A); hg4->pBoardGame->put_move(3,5,(_eplayer)PLAYER_B);
    CPPUNIT_ASSERT(NONE==hg4->whoWon());
    hg4->pBoardGame->put_move(1,0,(_eplayer)PLAYER_A); hg4->pBoardGame->put_move(3,6,(_eplayer)PLAYER_B);
    //cout<<*(hg4->pBoardGame)<<endl;
    CPPUNIT_ASSERT(NONE==hg4->whoWon());
}

void Test_HexGame::test_userMove(void)
{
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> choose: length 7 and 'x'"<<endl<<endl<<endl;
    hg1->usermenu();
    CPPUNIT_ASSERT(true==hg1->isUserPlayerA && 7==hg1->pBoardGame->GetBoardSize());
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> put your move as (0,0)"<<endl<<endl<<endl;
    CPPUNIT_ASSERT(0==hg1->yourMove());
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> put your move as (6,0)"<<endl<<endl<<endl;
    CPPUNIT_ASSERT(42==hg1->yourMove());
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> put your move as (3,3)"<<endl<<endl<<endl;
    CPPUNIT_ASSERT(24==hg1->yourMove());
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> press 'q'"<<endl<<endl<<endl;
    CPPUNIT_ASSERT(0==hg1->yourMove() && hg1->bExit);
}

void Test_HexGame::test_compMove(void)
{
    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> choose: length 7 and 'x'"<<endl<<endl<<endl;
    hg1->usermenu();
    CPPUNIT_ASSERT(true==hg1->isUserPlayerA && 7==hg1->pBoardGame->GetBoardSize());

    //put some moves:
    //(0,5)-x    (0,3)-o
    //(1,5)-x    (1,3)-o
    //(2,5)-x    (2,3)-o
    //(3,5)-x    (4,3)-o
    //(4,5)-x    (5,3)-o
    //(5,5)-x    (6,3)-o
    //(0,0)-x    (3,3)= node 24 - will be the best move in this situation - find this move
    hg1->pBoardGame->put_move(0,5,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(0,3,(_eplayer)PLAYER_B);
    hg1->pBoardGame->put_move(1,5,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(1,3,(_eplayer)PLAYER_B);
    hg1->pBoardGame->put_move(2,5,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(2,3,(_eplayer)PLAYER_B);
    hg1->pBoardGame->put_move(3,5,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(4,3,(_eplayer)PLAYER_B);
    hg1->pBoardGame->put_move(4,5,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(5,3,(_eplayer)PLAYER_B);
    hg1->pBoardGame->put_move(5,5,(_eplayer)PLAYER_A); hg1->pBoardGame->put_move(6,3,(_eplayer)PLAYER_B);
    hg1->pBoardGame->put_move(0,0,(_eplayer)PLAYER_A);  //the best move for o-PLAYER_B  will be (3,3)
    CPPUNIT_ASSERT(24==hg1->compMove());

    cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> choose: length 7 and 'o'"<<endl<<endl<<endl;
    hg2->usermenu();
    CPPUNIT_ASSERT(false==hg2->isUserPlayerA && 7==hg2->pBoardGame->GetBoardSize());

    //put some moves:
    //(6,0)-x    (0,1)-o
    //(5,1)-x    (1,1)-o
    //(4,2)-x    (1,2)-o
    //(5,2)-x    (2,2)-o
    //(3,4)-x    (3,2)-o
    //(4,4)-x    (4,1)-o
    //(5,4)-x    (0,5)-o
    //(4,5)-x    (1,5)-o
    //(3,6)-x    (2,4)-o
    //there is several the best moves: (3,3)=24|(4,3)=31|(5,3)=38 -
    hg2->pBoardGame->put_move(6,0,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(0,1,(_eplayer)PLAYER_B);
    hg2->pBoardGame->put_move(5,1,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(1,1,(_eplayer)PLAYER_B);
    hg2->pBoardGame->put_move(4,2,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(1,2,(_eplayer)PLAYER_B);
    hg2->pBoardGame->put_move(5,2,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(2,2,(_eplayer)PLAYER_B);
    hg2->pBoardGame->put_move(3,4,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(3,2,(_eplayer)PLAYER_B);
    hg2->pBoardGame->put_move(4,4,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(4,1,(_eplayer)PLAYER_B);
    hg2->pBoardGame->put_move(5,4,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(0,5,(_eplayer)PLAYER_B);
    hg2->pBoardGame->put_move(4,5,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(1,5,(_eplayer)PLAYER_B);
    hg2->pBoardGame->put_move(3,6,(_eplayer)PLAYER_A); hg2->pBoardGame->put_move(2,4,(_eplayer)PLAYER_B);
    Node BestMove = hg2->compMove();
    CPPUNIT_ASSERT( (24==BestMove) || (31==BestMove) || (38==BestMove));
}
